;(() => {
  // 交叉类型
  // const mergeFunc = <T, U>(arg1: T, arg2: U): T & U => {
  //   let res = {} as T & U
  //   res = Object.assign(arg1, arg2)
  //   return res
  // }
  // const mergeF = mergeFunc({ a: 'a', b: 'b' }, { c: 'c' })
  // console.log(mergeF)
  // 联合类型
  // const getLengthFunc = (content: string | number): number => {
  //   if (typeof content === 'string') {
  //     return content.length
  //   } else {
  //     return content.toString().length
  //   }
  // }
  // console.log(getLengthFunc('赫尔奥所大所大所多'))
  // console.log(getLengthFunc(123123123123))
  // 类型保护
  // const valueList = [123, 'abc']
  // const getRandomValue = () => {
  //   const number = Math.random() * 10
  //   if (number < 5) {
  //     return valueList[0]
  //   } else {
  //     return valueList[1]
  //   }
  // }
  // const item = getRandomValue()
  // 使用类型断言
  // if ((item as string).length) {
  //   console.log((item as string).length)
  // } else {
  //   console.log((item as number).toFixed())
  // }
  // 使用类型保护
  // function isString(value: number | string): value is string {
  //   return typeof value === 'string'
  // }
  // if (isString(item)) {
  //   return console.log(item.length)
  // } else {
  //   return console.log(item.toFixed(2))
  // }
  // string / number /boolean /symbol 中的一种
  // typeof类型保护
  // if (typeof item === 'string') {
  //   return console.log(item.length)
  // } else {
  //   return console.log(item.toFixed(2))
  // }
  // instanceof 类型保护
  // class Person {
  //   age: number = 18
  // }
  // class People {
  //   name: string = '胭脂'
  // }
  // function getRandomItem() {
  //   return Math.random() < 0.5 ? new Person() : new People()
  // }
  // const item = getRandomItem()
  // console.log(item)
  // if (item instanceof Person) {
  //   console.log(item.age)
  // } else {
  //   console.log(item.name)
  // }
  // null/undefined
  // let values: string = '123'
  // values = undefined
  // // string | undefined / string | null / string | null | undefined\
  // const sumFunc = (x: number, y?: number) => {
  //   return x + (y || 0)
  // }
  // const getLengthFunction = (value: string | null): number => {
  //   // if (value === null) {
  //   //   return 0
  //   // } else {
  //   //   return value.length
  //   // }
  //   return (value || '').length
  // }
  // console.log(getLengthFunction('asdasdasd'))
  // function getSplicedStr(num: number | null): string {
  //   function getRes(prefix: string) {
  //     return prefix + num!.toFixed().toString()
  //   }
  //   num = num || 0.1
  //   return getRes('yanzhi-')
  // }
  // console.log(getSplicedStr(3.05))
  // type TypeString = string
  // let str: TypeString
  // type PositionType<T> = { x: T; y: T }
  // const position: PositionType<number> = {
  //   x: 1,
  //   y: -1,
  // }
  // const position1: PositionType<string> = {
  //   x: 'left',
  //   y: 'top',
  // }
  // type Child<T> = {
  //   current: T
  //   child?: Child<T>
  // }
  // let ccc: Child<string> = {
  //   current: 'first',
  //   child: {
  //     current: 'first',
  //   },
  // }
  // console.log(ccc)
  // type Childs = Childs[] // 报错
  // 类型别名不可以继承
  // type Alias = {
  //   num: number
  // }
  // interface Interface {
  //   num: number
  // }
  // let _alias: Interface = {
  //   num: 123,
  // }
  // let _interface: Alias = {
  //   num: 123,
  // }
  // _alias = _interface
  // 类型别名不能使用extends 和 implements
  // 无法通过接口并且使用联合类型或者元祖 使用类型别名
  // 字面量类型
  // 字符串字面量 数字字面量
  // type Name = 'Lison'
  // const name: Name = 'Lison'
  // type Direction = 'a111' | 'b2222' | 'c333' | 'd4444'
  // function getDirectionFirstLetter(str: Direction) {
  //   return str.substring(0, 1)
  // }
  // console.log(getDirectionFirstLetter('d4444'))
  // type Age = 18 | 19 | 20 | 21
  // interface InfoInterface {
  //   name: string
  //   age: Age
  // }
  // const _info: InfoInterface = {
  //   name: '胭脂',
  //   age: 19,
  // }
  /*
     可辨识联合的两要素
    1.具有普通的单例类型属性
    2.一个类型别名包含了哪些类型的联合
 */
  interface Square {
    kind: 'square'
    size: number
  }

  interface Rectangle {
    kind: 'rectangle'
    height: number
    width: number
  }
  interface Circle {
    kind: 'circle'
    radius: number
  }

  type Shape = Square | Rectangle | Circle
  function assertNever(value: never): never {
    throw new Error('Unexpected object:' + value)
  }
  function getArea(s: Shape) {
    switch (s.kind) {
      case 'square':
        return s.size * s.size
      case 'rectangle':
        return s.height * s.width
      case 'circle':
        return Math.PI * s.radius ** 2
      default:
        return assertNever(s)
    }
  }
  const yuan: Circle = {
    kind: 'circle',
    radius: 5,
  }
  console.log(getArea(yuan))
})()
